import os
import time
import datetime
import json
from rest_framework import mixins, status, viewsets
from rest_framework.response import Response
from django.http import HttpResponse, JsonResponse
from django.shortcuts import render
from django.shortcuts import redirect
from wechatpy.utils import check_signature
from wechatpy.exceptions import InvalidSignatureException
from wechatpy.crypto import WeChatCrypto
from wechatpy import parse_message
from wechatpy.replies import TextReply  # 微信自动回复接口

from finance_c2c.local_settings import Config
from core.wchat.img import make_qr_img
from core.wchat.wx_base import WxPay
from core.wchat.get_web_user import GetWebUser
from core.wchat.models import WxUserInfo
from core.wchat.wx_base import WxBase
from apps.sales_man.models import BoundRelation, SalesMan
from core.tools.FormatXmlArray import FormatXmlArray
from apps.czb.task import task_kf_send_group_chat_image
from core.wchat.WXInstance import KLBWxBase, KLBWxPay
from apps.czb.models import Orders as CzbOrders
from rest_framework.permissions import IsAuthenticated
from rest_framework.authentication import SessionAuthentication
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from .serializers import H5PaySerializers, JsPaySerializer
from apps.supply_order.models import SupplyOrder, WomaiChildOrder
# from finance_c2c.local_settings import GGCardConfig

try:
    from urllib import urlencode
except Exception as e:
    print(e)
    from urllib.parse import urlencode


def login(request):
    scope = "snsapi_userinfo"
    wx = GetWebUser(scope)
    next_url = request.GET.get('next', '')
    if request.GET.get("code"):
        code = request.GET.get("code")
        wx.get_access_token(code)
        if wx.result_dict.get("access_token"):
            user_info = wx.get_user_info()
        else:
            return HttpResponse("权限出错")
        openid = user_info.get("openid")
        try:
            wx_user_info, created = WxUserInfo.objects.get_or_create(openid=openid)
            wx_user_info.update_info(user_info)
            request.session[Config.session_key] = wx_user_info
        except Exception as e:
            print(e)
            return HttpResponse("权限有问题")
        if next_url:
            return redirect(next_url)
        else:
            return JsonResponse(user_info)
    else:
        data = {"next": next_url}
        full_path = urlencode(data)
        re_url = "%s%s" % (Config.wx_login_path, full_path)
        url = wx.get_code(re_url)
        return redirect(url)


def loginGGcard(request):
    scope = "snsapi_userinfo"
    wx = GetWebUser(scope, config=GGCardConfig)
    next_url = request.GET.get('next', '')
    if request.GET.get("code"):
        code = request.GET.get("code")
        wx.get_access_token(code)
        if wx.result_dict.get("access_token"):
            user_info = wx.get_user_info()
        else:
            return HttpResponse("权限出错")
        # openid = user_info.get("openid")
        if next_url:
            return redirect(next_url)
        else:
            return JsonResponse(user_info)
    else:
        data = {"next": next_url}
        full_path = urlencode(data)
        re_url = "%s%s" % (Config.wx_login_path, full_path)
        url = wx.get_code(re_url)
        return redirect(url)


def index(request):
    if request.method == 'GET':
        # 验证公众号的流程
        signature = request.GET.get("signature", "")
        timestamp = request.GET.get("timestamp", "")
        nonce = request.GET.get("nonce", "")
        echostr = request.GET.get("echostr", "")
        try:
            check_signature(Config.token, signature, timestamp, nonce)
            return HttpResponse(echostr)
        except InvalidSignatureException:
            return HttpResponse("")
    if request.method == "POST":
        msg_signature = request.GET.get("msg_signature")
        timestamp = request.GET.get("timestamp")
        nonce = request.GET.get("nonce")
        crypto = WeChatCrypto(Config.token, Config.encoding_aes_key, Config.appid)
        decrypted_xml = crypto.decrypt_message(request.body, msg_signature, timestamp, nonce)
        array_data = FormatXmlArray.xml_to_array(decrypted_xml)  # 获取请求内容（自己解析）
        print(array_data, "array_data")
        from_openid = array_data.get("FromUserName")
        if array_data.get("MsgType") == "event":  # 事件推送
            if array_data.get("Event") == "subscribe":  # 关注
                if array_data.get("EventKey") and "qrscene_" in array_data.get("EventKey"):
                    event_key = array_data.get("EventKey").replace("qrscene_", "")
                    if Config.sales_id in event_key:  # 扫码
                        sales_id = event_key.replace(Config.sales_id, "")
                        BoundRelation.objects.create_relation(sales_id, from_openid)
                        # 回复
                        reply = TextReply(content=Config.c2c_reply, message=parse_message(decrypted_xml))
                        # 转换成 XML
                        xml = reply.render()
                        return HttpResponse(xml, content_type="application/xml")
                    elif "IMCoffee" in event_key:
                        coffee_data = json.loads(event_key)
                        key = coffee_data.get("IMCoffee")
                        content_text = "<a href='%s'>点击领取好友优惠券</a>"
                        content_url = Config.coffee_get_coupon % key
                        reply = TextReply(content=content_text % content_url, message=parse_message(decrypted_xml))
                        # 转换成 XML
                        xml = reply.render()
                        return HttpResponse(xml, content_type="application/xml")
                else:
                    # 默认进入出加油信息
                    # reply = TextReply(content=Config.jiayou % 3, message=parse_message(decrypted_xml))
                    reply = TextReply(content="感谢关注IMCA", message=parse_message(decrypted_xml))
                    # 转换成 XML
                    xml = reply.render()
                    # 异步发送消息
                    # task_kf_send_group_chat_image.delay(from_openid)
                    return HttpResponse(xml, content_type="application/xml")
            if array_data.get("Event") == "SCAN":  # 扫码
                event_key = array_data.get("EventKey")
                if Config.sales_id in event_key:
                    sales_id = event_key.replace(Config.sales_id, "")
                    BoundRelation.objects.create_relation(sales_id, from_openid)
                    # 回复
                    reply = TextReply(content=Config.c2c_reply, message=parse_message(decrypted_xml))
                    # 转换成 XML
                    xml = reply.render()
                    return HttpResponse(xml, content_type="application/xml")
                    # if array_data.get("Event") == "CLICK":  # 点击
                    #     if array_data.get("EventKey") == "tuiguangtu":
                    #         make_tg_img(from_openid)
                    #     return HttpResponse("success")
                if "jiayou_user_id_" in event_key:
                    user_id = event_key.replace("jiayou_user_id_", "")
                    reply = TextReply(content=Config.jiayou % user_id, message=parse_message(decrypted_xml))
                    # 转换成 XML
                    xml = reply.render()
                    # 异步发送消息
                    task_kf_send_group_chat_image.delay(from_openid)
                    return HttpResponse(xml, content_type="application/xml")
                if "up_user_id_" in event_key:
                    user_id = event_key.replace("up_user_id_", "")
                    reply = TextReply(content=Config.shopping % user_id, message=parse_message(decrypted_xml))
                    # 转换成 XML
                    xml = reply.render()
                    # 异步发送消息
                    task_kf_send_group_chat_image.delay(from_openid)
                    return HttpResponse(xml, content_type="application/xml")
                if "IMCoffee" in event_key:
                    coffee_data = json.loads(event_key)
                    key = coffee_data.get("IMCoffee")
                    content_text = "<a href='%s'>点击领取好友优惠券</a>"
                    content_url = Config.coffee_get_coupon % key
                    reply = TextReply(content=content_text % content_url, message=parse_message(decrypted_xml))
                    # 转换成 XML
                    xml = reply.render()
                    return HttpResponse(xml, content_type="application/xml")
        elif array_data.get("MsgType") == "text":
            if array_data.get("Content") == "领酒":
                reply = TextReply(content=Config.lingjiu, message=parse_message(decrypted_xml))
                # 转换成 XML
                xml = reply.render()
                return HttpResponse(xml, content_type="application/xml")

        else:
            pass
        reply = TextReply(content='有任何问题请致电 010-84874127，工作日9：00---18：00，小优都会认真接听您的电话。',
                          message=parse_message(decrypted_xml))
        # 转换成 XML
        xml = reply.render()
        return HttpResponse(xml, content_type="application/xml")


def wx_file(request, file_name):
    base_path = os.path.dirname(os.path.abspath(__file__))
    # files = 'MP_verify_nd1LCImhoNGn4n8G.txt'

    file_path = os.path.join(base_path, file_name).replace('\\', '/')
    image_data = open(file_path, "rb").read()
    response = HttpResponse(image_data)
    response["Content-Disposition"] = 'attchmet;filename=%s' % file_name
    return response


def share(request):
    """
    微信分享
    :param request:
    :return:
    """
    url = request.GET.get("url", None)
    # url = quote(url)
    print(url, "share request url")
    wx_base = WxBase(config='kalaibao')
    share_content = wx_base.get_sign(url)
    return JsonResponse(share_content)


# 用来测试前后端分离分享
def share_test(request):
    return render(request, "wx/share_test.html")


# 用来测试分享
def c2c_share(request):
    sales_id = request.GET.get("sid")
    shared = request.GET.get("shared")
    sales_obj = SalesMan.objects.get(pk=sales_id)
    channel_img_queryset = sales_obj.channel.channelshareimg_set.all()
    expire_time = sales_obj.expire_time
    now_time = datetime.datetime.now()
    if expire_time and expire_time > now_time:
        path = sales_obj.scene_qr_code
    else:
        make_qr_img(sales_obj, short=False)
        path = sales_obj.scene_qr_code
    config_path = Config.no_protocol
    path = config_path + path
    for i in channel_img_queryset:
        i.img = config_path + i.img.url
        i.shared_img = config_path + i.shared_img.url
    return render(request, "c2c/share.html", locals())


def pay_page(request):
    return render(request, "wx/pay.html")


def pay_page_h5(request):
    return render(request, "wx/h5_pay.html")


def pay(request):
    openid = request.GET.get("openid")
    total_fee = 1
    wx_pay = WxPay()
    trade_type = "JSAPI"
    body = "优品会员支付"
    total_fee = str(total_fee)
    notify_url = Config.host + "/mp/pay_notice"
    # 下单
    data = {"total_fee": total_fee,
            "trade_type": trade_type,
            "body": body,
            }
    response = wx_pay.order.create(trade_type, body, total_fee, notify_url, user_id=openid)
    prepay_id = response.get("prepay_id")
    nonce_str = response.get("nonce_str")
    timestamp = int(time.time())
    response["package"] = "prepay_id=%s" % prepay_id
    response["timestamp"] = str(timestamp)
    response.pop("mch_id")
    # 签名
    sign_content = wx_pay.jsapi.get_jsapi_signature(prepay_id, timestamp=timestamp, nonce_str=nonce_str)
    response["paySign"] = sign_content
    return JsonResponse(response)


def pay_notice(request):
    xml = request.body
    wx_pay = WxPay()
    try:
        data = wx_pay.parse_payment_result(xml)
    except Exception as e:
        print(e, "微信通知")
        raise HttpResponse(e)
    print(data, "微信支付结果通知")
    out_trade_no = data.get("out_trade_no")
    attach = data.get("attach")
    if attach == "czb":
        czb_orders = CzbOrders.objects.get(out_trade_no=out_trade_no)
        czb_orders.update_pay_result(1)  # 1:支付成功
        czb_orders.save()
    else:
        supply_orders = SupplyOrder.objects.get(out_trade_no=out_trade_no)
        supply_orders.update_trade_type_fixed(pay_type=4)  # 更新订单
        WomaiChildOrder.objects.update_pay_result(supply_orders, pay_type="yl")  # 通过支付结果更新其他数据
    re = {"return_code": "SUCCESS", "return_msg": "OK"}
    re = FormatXmlArray.array_to_xml(re)
    return HttpResponse(re)


def pay_test_notice(request):
    if request.method == "POST":
        re = {"return_code": "SUCCESS", "return_msg": "OK"}
        re = FormatXmlArray.array_to_xml(re)
        return HttpResponse(re)
    else:
        return HttpResponse("hello world")


# 获取微信扫码关注二维码连接
def get_scan_code_link(request):
    """
    获取微信扫码关注二维码连接
    :param request:
    :return:
    """
    content = request.GET.get("content")
    url = KLBWxBase.get_qr_url(content, short=False)
    return HttpResponse(url)


# H5微信支付
class H5WxPayAPIView(mixins.CreateModelMixin, viewsets.GenericViewSet):
    permission_classes = (IsAuthenticated,)
    authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)
    serializer_class = H5PaySerializers

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        wx_order_instance = self.perform_create(serializer)
        mweb_url = wx_order_instance.mweb_url
        data = dict()
        data["out_trade_no"] = wx_order_instance.out_trade_no
        data["mweb_url"] = mweb_url
        return Response(data, status=status.HTTP_201_CREATED)

    def perform_create(self, serializer):
        return serializer.save()


# 微信公众号支付
class JsWxPayAPIView(mixins.CreateModelMixin, viewsets.GenericViewSet):
    permission_classes = (IsAuthenticated,)
    authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)
    serializer_class = JsPaySerializer

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        wx_order_instance = self.perform_create(serializer)
        prepay_id = wx_order_instance.prepay_id
        data = KLBWxPay.jsapi.get_jsapi_params(prepay_id)
        return Response(data, status=status.HTTP_201_CREATED)

    def perform_create(self, serializer):
        return serializer.save()
